#!/usr/bin/python3
# coding: utf-8
# file: orm.py
# mysql 对象 关系
# 2018-06-20


class Field(object):
	'字段类型基类'
	def __init__(self, name, column_type, primary_key, default):
		self.name = name
		self.column_type = column_type
		self.primary_key = primary_key
		self.default = default

	def __str__(self):
		return '<%s: %s: %s>' % (self.__class__.__name__, self.column_type, self.name)

class StringField(Field):
	'字段类型 - 字符串'
	def __init__(self, name=None, primary_key=False, default=None, ddl='varchar(100)'):
		super().__init__(name, ddl, primary_key, default)

def create_args_string(num):
    L = []
    for n in range(num):
        L.append('?')
    return ', '.join(L)

class ModelMetaclass(type):
	'Model类的元类'
	def __new__(cls, name, bases, attrs):
		if name=='Model':
			return type.__new__(cls, name, bases, attrs)

		tableName = attrs.get('__table__', None) or name
		mappings = dict()
		primaryKey = None
		fields = []

		for k, v in attrs.items():
			if isinstance(v, Field):
				mappings[k] = v
				if v.primary_key:
					if primaryKey:
					    raise Exception('Duplicate primary key for field: %s' % k)
					primaryKey = k
				else:
					fields.append(k)
		if not primaryKey:
			raise Exception('Primary key not found.')

		for k in mappings.keys():
			attrs.pop(k)

		escaped_fields = list(map(lambda f: '`%s`' % f, fields))
		attrs['__mappings__'] = mappings
		attrs['__table__'] = tableName
		attrs['__primary_key__'] = primaryKey # 主键属性名
		attrs['__fields__'] = fields # 除主键外的属性名
		attrs['__select__'] = 'select `%s`, %s from `%s`' % (primaryKey, ', '.join(escaped_fields), tableName)
		attrs['__insert__'] = 'insert into `%s` (%s, `%s`) values (%s)' % (tableName, ', '.join(escaped_fields), primaryKey, create_args_string(len(escaped_fields) + 1))
		attrs['__update__'] = 'update `%s` set %s where `%s`=?' % (tableName, ', '.join(map(lambda f: '`%s`=?' % (mappings.get(f).name or f), fields)), primaryKey)
		attrs['__delete__'] = 'delete from `%s` where `%s`=?' % (tableName, primaryKey)
		return type.__new__(cls, name, bases, attrs)

class Model(dict, metaclass=ModelMetaclass):
	'Model基类'
	def __init__(sef, **kw):
		super(Model, self).__init__(**kw)

class User(Model):
	'Model类'
	__table__ = 'user'

	email = StringField(primary_key=True)
	email2 = StringField()


print(User.__select__)